#pragma once
#include <condition_variable>
#include <mutex>
#include <queue>

namespace boltDB {
template <class T>
class Channel {
 public:
  Channel() = default;
  ~Channel() = default;

  // 向管道中插入元素
  void Put(T element) {
    std::unique_lock<std::mutex> lk(m_);
    queue_.push(std::move(element));
    lk.unlock();
    cv_.notify_all();
  }

  // 向管道中读取元素，如果此时管道为空就会被挂起，直到有元素送达
  auto Get() -> T {
    std::unique_lock<std::mutex> lk(m_);
    cv_.wait(lk, [&]() { return !queue_.empty(); });
    T element = std::move(queue_.front());
    queue_.pop();
    return element;
  }

 private:
  std::mutex m_;
  std::condition_variable cv_;
  std::queue<T> queue_;
};
}  // namespace boltDB